using System;
using System.Xml;
using XmlObjects;
using MbUnit.Framework;

namespace UnitTests
{
	[TestFixture]
	public class TestXmlReader : XmlTestsBase
	{
		[Test, ExpectedException(typeof (ArgumentNullException))]
		public void TestThrowExceptionOnNullParentNode()
		{
			myObject.ReadFrom(null);
		}

		[Test]
		public void TestReadAttributes()
		{
			Assert.AreEqual(myObject.AttributeOne, attributeOne);
			Assert.AreEqual(myObject.AttributeTwo, attributeTwo);
		}

		[Test]
		public void TestReadElements()
		{
			Assert.AreEqual(myObject.ElementOne, elementOne);
			Assert.AreEqual(myObject.ElementTwo, elementTwo);
			Assert.AreEqual(myObject.ElementThree, elementThree);
		}

		[Test]
		public void TestReadObjectElement()
		{
			Assert.AreEqual(myObject.ObjectElementOne.AttributeOne, attributeOne);
			Assert.AreEqual(myObject.ObjectElementOne.AttributeTwo, attributeTwo);
			Assert.AreEqual(myObject.ObjectElementOne.ElementOne, elementOne);
			Assert.AreEqual(myObject.ObjectElementOne.ElementTwo, elementTwo);
			Assert.AreEqual(myObject.ObjectElementOne.ElementThree, elementThree);
		}

		[Test]
		public void TestReadSwitchElement()
		{
			Assert.AreEqual(typeof(MyCoolAnotherObject).ToString(), myObject.MyAnotherObject.GetType().ToString());
		}

		[Test]
		public void TestReadSwitchElementWithDefault()
		{
			Assert.AreEqual(typeof(MyCoolAnotherObject).ToString(), myObject.MyCoolObject.GetType().ToString());
			MyCoolAnotherObject myCoolAnotherObject = (MyCoolAnotherObject) myObject.MyCoolObject;
			Assert.AreEqual(myCoolAnotherObject.MyProperty, myProperty);
		}
	}

	[XmlElement("myObject")]
	public class MyObject : DocumentElement
	{
		private string attributeOne;
		private int attributeTwo;
		private string elementOne;
		private int elementTwo;
		private double elementThree;
		private MyObject myObject;
		private MyAnotherObject myAnotherObject;

		[XmlAttribute("attributeOne")]
		public string AttributeOne
		{
			get { return attributeOne; }
			set { attributeOne = value; }
		}

		[XmlAttribute("attributeTwo")]
		public int AttributeTwo
		{
			get { return attributeTwo; }
			set { attributeTwo = value; }
		}

		[XmlElement("elementOne")]
		public string ElementOne
		{
			get { return elementOne; }
			set { elementOne = value; }
		}

		[XmlElement("elementTwo")]
		public int ElementTwo
		{
			get { return elementTwo; }
			set { elementTwo = value; }
		}

		[XmlElement("elementThree")]
		public double ElementThree
		{
			get { return elementThree; }
			set { elementThree = value; }
		}

		[XmlElement("objectElementOne")]
		public MyObject ObjectElementOne
		{
			get { return myObject; }
			set { myObject = value; }
		}

		[XmlElement("myAnotherObject")]
		public MyAnotherObject MyAnotherObject
		{
			get { return myAnotherObject; }
			set { myAnotherObject = value; }
		}

		private MyAnotherObject myCoolObject;


		[XmlElement("myCoolObject")]
		public MyAnotherObject MyCoolObject
		{
			get { return myCoolObject; }
			set { myCoolObject = value; }
		}
	}

	[SuperClass("type", DefaultType = typeof (MyCoolAnotherObject))]
	[SubClass(typeof (MyCoolAnotherObject), Id = "coolAnotherObject")]
	public class MyAnotherObject : DocumentElement
	{
	}

	public class MyCoolAnotherObject : MyAnotherObject
	{
		private string myProperty;

		[XmlAttribute("myProperty")]
		public string MyProperty
		{
			get { return myProperty; }
			set { myProperty = value; }
		}
	}
}